#include "CSphere.h"

using namespace Content;
using namespace Util;

CSphere::CSphere(const float r)
{
  radius = r;
  segments = 36;
  levels = segments/2;
  vertices = 0;
  indices = 0;
  numVertices = 3*segments*2+4*segments*(levels-2);
  numTriangles = 2*segments+(levels-2)*segments*2;
  numIndices = numTriangles*3;

  LOG_INFO("verts:"<<numVertices)
  LOG_INFO("tris: " <<numTriangles)
  LOG_INFO("inds: "<<numIndices)
  initVertices();
  initIndices();
}

void CSphere::initVertices()
{
  vertices = new PrimitiveVertex[numVertices]();

  LOG_INFO("lEVELS: "<<levels)
  LOG_INFO("r: " << radius)
  PrimitiveVertex pv;

  pv.tX=0.0f;
  pv.tY=0.0f;

  float DTOR=PI/180.0f;
  int dtheta=180/(levels);
  LOG_INFO(dtheta)
  int dphi=360/segments;
   int n = 0;
   int m= 0;
   int theta,phi;
   for (theta=-90;theta<=90-dtheta;theta+=dtheta) 
   {
      for (phi=0;phi<=360-dphi;phi+=dphi) 
      {
         pv.x = cos(theta*DTOR) * cos(phi*DTOR) * radius;
         pv.y = cos(theta*DTOR) * sin(phi*DTOR) * radius;
         pv.z = sin(theta*DTOR) * radius;
         pv.nX = pv.x;
         pv.nY = pv.y;
         pv.nZ = pv.z;

         vertices[n] = pv;
         n++;

         pv.x = cos((theta+dtheta)*DTOR) * cos(phi*DTOR) * radius;
         pv.y = cos((theta+dtheta)*DTOR) * sin(phi*DTOR)* radius;
         pv.z = sin((theta+dtheta)*DTOR) * radius;
         pv.nX = pv.x;
         pv.nY = pv.y;
         pv.nZ = pv.z;

         vertices[n] = pv;
         n++;

         if (theta + dtheta < 90)
         {
         pv.x = cos((theta+dtheta)*DTOR) * cos((phi+dphi)*DTOR) * radius;
         pv.y = cos((theta+dtheta)*DTOR) * sin((phi+dphi)*DTOR) * radius;
         pv.z = sin((theta+dtheta)*DTOR) * radius;
         pv.nX = pv.x;
         pv.nY = pv.y;
         pv.nZ = pv.z;
         }
         else
         {
         pv.x = cos((theta)*DTOR) * cos((phi+dphi)*DTOR) * radius;
         pv.y = cos((theta)*DTOR) * sin((phi+dphi)*DTOR) * radius;
         pv.z = sin((theta)*DTOR) * radius; 
         pv.nX = pv.x;
         pv.nY = pv.y;
         pv.nZ = pv.z;

         }

         vertices[n] = pv;
         n++;

         if (theta > -90 && theta+dtheta < 90)
         {
            pv.x = cos(theta*DTOR) * cos((phi+dphi)*DTOR) * radius;
            pv.y = cos(theta*DTOR) * sin((phi+dphi)*DTOR) * radius;
            pv.z = sin(theta*DTOR) * radius;
            pv.nX = pv.x;
            pv.nY = pv.y;
            pv.nZ = pv.z;

            vertices[n] = pv;
            n++;
         }
      }
   }
}

void CSphere::initIndices()
{
  indices = new WORD[numIndices]();

  //top cone
  int baseInd = 0;
  int baseVert = 0;
  for (int i= 0; i< segments; ++i )
  {
    indices[baseInd] = baseVert;
    indices[baseInd+1] = baseVert+2;
    indices[baseInd+2] = baseVert+1;
    baseInd+=3;
    baseVert+=3;
  }

  for (int i = 0; i<levels-2;++i)
  {
    for (int j = 0; j < segments;++j)
    {
      indices[baseInd]=baseVert;
      indices[baseInd+1]=baseVert+2;
      indices[baseInd+2]=baseVert+1;

      indices[baseInd+3]=baseVert;
      indices[baseInd+4]=baseVert+3;
      indices[baseInd+5]=baseVert+2;
      baseInd+=6;
      baseVert+=4;
     }
  }

  //bottom cone
  for (int i= 0; i< segments; ++i )
  {
    indices[baseInd] = baseVert+1;
    indices[baseInd+1] = baseVert;
    indices[baseInd+2] = baseVert+2;
    baseInd+=3;
    baseVert+=3;
  }
}

float CSphere::getRadius()
{
  return radius;
}